package com.xia.controller;

import com.github.pagehelper.PageHelper;
import com.xia.controller.result.Result;
import com.xia.controller.result.ResultCode;
import com.xia.domain.User;
import com.xia.feign.PermissionFeign;
import com.xia.service.UserService;
import com.xia.utils.JwtUtils;
import com.xia.utils.LogUtils;
import com.xia.utils.UserUtils;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private PermissionFeign permissionFeign;
    @Autowired
    private UserUtils userUtils;
    @Autowired
    private LogUtils logUtils;


    /**
     * 注册
     * 在方法上使用@GlobalTransactional注解，表示该方法是一个全局事务的边界
     * 当方法执行时，会自动开启一个全局事务，方法执行成功后提交事务，若发生异常则回滚事务
     * 主要用于分布式事务管理，确保跨多个数据源或服务的操作保持事务一致性
     */
    @GlobalTransactional
    @PostMapping("/register")
    public Result register(@RequestBody User user, HttpServletRequest request) {
        if (userUtils.isEmpty(user) == null) { // 用户信息不为空且唯一
            if (userService.register(user) == 1) { // 是受影响的行数，则注册成功
                // 将注册成功的用户绑定为普通用户角色
                // 将获取到的用户ID传递给permissionFeign绑定为普通用户
                permissionFeign.bindDefaultRole(userUtils.findUserId(user));
//                int i = 1 / 0; // todo 测试事务回滚
                // 调用日志工具类，记录日志
                logUtils.recordLog(user, request);
                return new Result(ResultCode.SUCCESS, "注册成功");
            } else {
                return new Result(ResultCode.FAIL, "注册失败，用户已存在");
            }
        } else { // 用户信息为空
            return userUtils.isEmpty(user);
        }
    }

    /**
     * 登录
     */
    @GlobalTransactional
    @PostMapping("/login")
    public Result login(@RequestBody User user, HttpServletRequest request) {
        if (user.getUsername() != null && user.getPassword() != null) { // 判断账户和密码不能为空
            User login = userService.login(user.getUsername(), user.getPassword());
            if (login != null) { // 判断用户是否存在
                // 生成token，登陆成功
                String token = JwtUtils.generateToken(login.getUsername());
                // 获取登录后的用户ID
                Long userId = userUtils.findUserId(login);
                // 通过permission查询用户角色码
                String userRoleCode = permissionFeign.getUserRoleCode(userId);
                // 调用日志工具类，记录日志
                logUtils.recordLog(user, request);
                return new Result(ResultCode.SUCCESS, "登录成功：" + userRoleCode, token);
            } else {
                return new Result(ResultCode.USER_NOT_EXISTS, "用户不存在");
            }
        } else {
            return new Result(ResultCode.USER_NAME_OR_PASSWORD_EMPTY, "用户名或密码不能为空");
        }
    }

    /**
     * 获取用户列表
     */
    @GlobalTransactional
    @GetMapping("/users")
    public Result getUserList(
            @RequestParam(value = "pageNum", defaultValue = "1") int pageNum, // 页码，默认第一页
            @RequestParam(value = "pageSize", defaultValue = "3") int pageSize, // 每页数量，默认每页3条数据
            Authentication authentication, // 获取Token密钥，获取登录角色信息
            HttpServletRequest request
    ) {
        // 获取当前登录用户
        String loginUserName = authentication.getName();
        User userGetByName = userUtils.getUserByName(loginUserName); // 需要确保用户名唯一
        // 通过permission查询用户角色码
        String userRoleCode = permissionFeign.getUserRoleCode(userGetByName.getUserId());
        // todo 可以使用增强switch，但是只能Java 14+以上
        switch (userRoleCode) {
            case "user": // 获取自己的用户信息
                User userByUser = userService.getUserInfo(userUtils.getUserByName(loginUserName).getUserId());
                if(userByUser != null){
                    // 调用日志工具类，记录日志
                    logUtils.recordLog(userGetByName, request);
                    return new Result(ResultCode.SUCCESS, "获取用户信息成功", userByUser);
                }
                else
                    return new Result(ResultCode.USER_NOT_EXISTS, "用户不存在");
            case "admin": // 获取管理员和普通用户的用户列表
                // 开启分页
                PageHelper.startPage(pageNum, pageSize);
                // 调用日志工具类，记录日志
                logUtils.recordLog(userGetByName, request);
                return new Result(ResultCode.SUCCESS, "获取用户信息成功", userUtils.getHaveRoleUserList()
                        .stream()
                        .filter(u -> {
                            String role = u.getRole();
                            return role != null && (role.equals("user") || role.equals("admin"));
                        })
                        .toList());
            case "super_admin": // 获取所有用户的用户列表
                // 开启分页
                PageHelper.startPage(pageNum, pageSize);
                // 调用日志工具类，记录日志
                logUtils.recordLog(userGetByName, request);
                return new Result(ResultCode.SUCCESS, "获取用户信息成功", userUtils.getHaveRoleUserList());
            default:
                return new Result(ResultCode.FAIL, "角色异常");
        }
    }

    /**
     * 获取单个用户信息
     */
    @GlobalTransactional
    @GetMapping(value = "/{userId}")
    public Result getUserInfo(@PathVariable Long userId,
                              Authentication authentication, // 获取Token密钥，获取登录角色信息
                              HttpServletRequest request
    ) {
        // 获取当前登录用户
        String loginUserName = authentication.getName();
        User userGetByName = userUtils.getUserByName(loginUserName); // 需要确保用户名唯一
        // 通过permission查询用户角色码
        String userRoleCode = permissionFeign.getUserRoleCode(userGetByName.getUserId());
        switch (userRoleCode) {
            case "user": // 获取自己的用户信息
                User userByUser = userService.getUserInfo(userUtils.getUserByName(loginUserName).getUserId());
                if(userByUser != null){
                    // 调用日志工具类，记录日志
                    logUtils.recordLog(userGetByName, request);
                    return new Result(ResultCode.SUCCESS, "获取用户信息成功", userByUser);
                }
                else
                    return new Result(ResultCode.USER_NOT_EXISTS, "用户不存在");
            case "admin": // 获取管理员和普通用户的用户
                String userRoleCode1 = permissionFeign.getUserRoleCode(userService.getUserInfo(userId).getUserId());
                if (userRoleCode1.equals("user") || userRoleCode1.equals("admin")) {
                    // 调用日志工具类，记录日志
                    logUtils.recordLog(userGetByName, request);
                    return new Result(ResultCode.SUCCESS, "获取用户信息成功", userService.getUserInfo(userId));
                } else if (userRoleCode1.equals("super_admin")) {
                    return new Result(ResultCode.UNAUTHORIZED, "未授权");
                }
            case "super_admin": // 获取所有用户的用户
                // 调用日志工具类，记录日志
                logUtils.recordLog(userGetByName, request);
                return new Result(ResultCode.SUCCESS, "获取用户信息成功", userService.getUserInfo(userId));
            default:
                return new Result(ResultCode.FAIL, "角色异常");
        }
    }

    /**
     * 修改用户信息
     */
    @GlobalTransactional
    @PutMapping("/{userId}")
    public Result updateUserInfo(@PathVariable Long userId, // 需要修改的用户ID
                                 @RequestBody User user,
                                 Authentication authentication, // 获取Token密钥，获取登录角色信息，获取操作者的信息
                                 HttpServletRequest request
    ) {
        // 获取当前登录用户
        String loginUserName = authentication.getName();
        User userGetByName = userUtils.getUserByName(loginUserName); // 需要确保用户名唯一
        // 通过permission查询用户角色码
        String userRoleCode = permissionFeign.getUserRoleCode(userGetByName.getUserId());
        switch (userRoleCode) {
            case "user": // 修改自己的用户信息
                if (userService.updateUserInfo(userUtils.getUserByName(loginUserName)) > 0) { // 有受影响的行数，说明修改成功
                    // 调用日志工具类，记录日志
                    logUtils.recordLog(userGetByName, request);
                    return new Result(ResultCode.SUCCESS, "修改用户信息成功");
                }
                return new Result(ResultCode.FAIL, "修改用户信息失败");
            case "admin": // 修改自己和普通用户
                String userRoleCode1 = permissionFeign.getUserRoleCode(userService.getUserInfo(userId).getUserId());
                if (userRoleCode1.equals("user") || userRoleCode1.equals("admin")) {
                    if (userService.updateUserInfo(user) > 0) { // 有受影响的行数，说明修改成功
                        // 调用日志工具类，记录日志
                        logUtils.recordLog(userGetByName, request);
                        return new Result(ResultCode.SUCCESS, "修改用户信息成功");
                    }
                    return new Result(ResultCode.FAIL, "修改用户信息失败");
                } else if (userRoleCode1.equals("super_admin")) {
                    return new Result(ResultCode.UNAUTHORIZED, "未授权");
                }
            case "super_admin": // 修改所有用户的用户
                if (userService.updateUserInfo(user) > 0) { // 有受影响的行数，说明修改成功
                    // 调用日志工具类，记录日志
                    logUtils.recordLog(userGetByName, request);
                    return new Result(ResultCode.SUCCESS, "修改用户信息成功");
                }
                return new Result(ResultCode.FAIL, "修改用户信息失败");
            default:
                return new Result(ResultCode.FAIL, "角色异常");
        }
    }

    /**
     * 重置密码，使用JSON数据传输
     */
    @GlobalTransactional
    @PostMapping("/reset-Password")
    public Result resetPassword(@RequestBody String username,
                                Authentication authentication, // 获取Token密钥，获取登录角色信息
                                HttpServletRequest request
    ) {
        // 获取当前登录用户
        String loginUserName = authentication.getName();
        User userGetByName = userUtils.getUserByName(loginUserName); // 需要确保用户名唯一
        // 通过permission查询用户角色码
        String userRoleCode = permissionFeign.getUserRoleCode(userGetByName.getUserId());
        switch (userRoleCode) {
            case "user": // 重置自己的用户信息
                if (userService.resetPassword(loginUserName) > 0) { // 有受影响的行数，说明重置成功
                    // 调用日志工具类，记录日志
                    logUtils.recordLog(userGetByName, request);
                    return new Result(ResultCode.SUCCESS, "重置密码成功");
                }
                return new Result(ResultCode.FAIL, "重置密码失败");
            case "admin": // 重置自己和普通用户的密码
                User user = userUtils.getUserByName(username);
                if (user == null) {
                    return new Result(ResultCode.USER_NOT_FOUND, "用户不存在");
                }
                String userRoleCode1 = permissionFeign.getUserRoleCode(user.getUserId());
                if (userRoleCode1.equals("user") || userRoleCode1.equals("admin")) {
                    // 调用日志工具类，记录日志
                    logUtils.recordLog(userGetByName, request);
                    if (userService.resetPassword(username) > 0) { // 有受影响的行数，说明重置成功
                        return new Result(ResultCode.SUCCESS, "重置密码成功");
                    }
                    return new Result(ResultCode.FAIL, "重置密码失败");
                } else if (userRoleCode1.equals("super_admin")) {
                    return new Result(ResultCode.UNAUTHORIZED, "未授权");
                }
            case "super_admin": // 重置所有用户的用户
                if (userService.resetPassword(username) > 0) { // 有受影响的行数，说明重置成功
                    // 调用日志工具类，记录日志
                    logUtils.recordLog(userGetByName, request);
                    return new Result(ResultCode.SUCCESS, "重置密码成功");
                }
                return new Result(ResultCode.FAIL, "重置密码失败");
            default:
                return new Result(ResultCode.FAIL, "角色异常");
        }
    }

    /**
     * 超管调用，给管理员降级为普通用户
     */
    @GlobalTransactional
    @PostMapping("/downgrade/{userId}")
    public Result downgrade(@PathVariable Long userId,
                            Authentication authentication, // 获取Token密钥，获取登录角色信息
                            HttpServletRequest request
    ) {
        // 获取当前登录用户
        String loginUserName = authentication.getName();
        User userGetByName = userUtils.getUserByName(loginUserName); // 需要确保用户名唯一
        // 通过permission查询用户角色码
        String userRoleCode = permissionFeign.getUserRoleCode(userGetByName.getUserId());
        if (userRoleCode.equals("super_admin")) { // 确认是超管
            if (permissionFeign.getUserRoleCode(userId).equals("user")) {
                return new Result(ResultCode.USER_IS_ADMIN, "用户已经是普通用户");
            }
            if (permissionFeign.downgradeToUser(userId) > 0) {
                // 调用日志工具类，记录日志
                logUtils.recordLog(userGetByName, request);
                return new Result(ResultCode.SUCCESS, "降级成功");
            }
            return new Result(ResultCode.FAIL, "降级失败");
        }
        return new Result(ResultCode.UNAUTHORIZED, "未授权");
    }

    /**
     * 超管调用，给普通用户升级为管理员
     */
    @GlobalTransactional
    @PostMapping("/upgrade/{userId}")
    public Result upgrade(@PathVariable Long userId,
                          Authentication authentication, // 获取Token密钥，获取登录角色信息
                          HttpServletRequest request
    ) {
        // 获取当前登录用户
        String loginUserName = authentication.getName();
        User userGetByName = userUtils.getUserByName(loginUserName); // 需要确保用户名唯一
        // 通过permission查询用户角色码
        String userRoleCode = permissionFeign.getUserRoleCode(userGetByName.getUserId());
        if (userRoleCode.equals("super_admin")) {
            if (permissionFeign.getUserRoleCode(userId).equals("admin")) {
                return new Result(ResultCode.USER_IS_ADMIN, "用户已经是管理员");
            }
            if (permissionFeign.upgradeToAdmin(userId) > 0) {
                // 调用日志工具类，记录日志
                logUtils.recordLog(userGetByName, request);
                return new Result(ResultCode.SUCCESS, "升级成功");
            }
            return new Result(ResultCode.FAIL, "升级失败");
        }
        return new Result(ResultCode.UNAUTHORIZED, "未授权");
    }
}
